﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace ZL_Framework
{
    /// <summary>
    /// 音频管理器
    /// </summary>
    [StartManagerAttribute]
    public class AudioManager : MonoSingleton<AudioManager>
    {
        /// <summary>
        /// 全局音量
        /// </summary>
        public static float audioVolum = 1;
        /// <summary>
        /// 是否播放背景音乐
        /// </summary>
        public static bool isPlayBGM = true;

        public Dictionary<string, AudioItem> CurrentBGM = new Dictionary<string, AudioItem>();
        public List<AudioItem> AllAudioItem = new List<AudioItem>();

        private GameObject audioItem;

        public string CommonAudioPath
        {
            get
            {
                return AppConfig.Instance.Config.ResPath + "/CommonAudio";
            }
        }

        protected override void Destroy()
        {
            CurrentBGM = null;
        }

        protected override void Init()
        {
            LoadAudioItem();
        }

        /// <summary>
        /// 播放背景音乐
        /// </summary>
        /// <param name="_ab">ab包</param>
        /// <param name="_bgmName">音乐名称（Assets下完整路径， 带文件格式后缀）</param>
        /// <param name="isAB"></param>
        /// <param name="_volum"></param>
        public void PlayBGM(string _ab, string _bgmName, bool isAB = true, float _volum = 1)
        {
            if (!AudioManager.isPlayBGM)
                return;

            StartCoroutine(PlayAudio(_ab, _bgmName, true, null, isAB, _volum));
        }

        /// <summary>
        /// 播放公共音频（音频文件需要放在 Assets/AssetBundles/CommonAudio 路径下）
        /// </summary>
        /// <param name="_audioName">音乐名称（非全路径，只要名字）</param>
        /// <param name="action">音效结束事件</param>
        /// <param name="isAB"></param>
        /// <param name="_volum"></param>
        public void PlayCommonAudio(string _audioName, Action action = null, bool isAB = true, float _volum = 1)
        {
            StartCoroutine(PlayAudio(CommonAudioPath, CommonAudioPath + _audioName, false, action, isAB, _volum));
        }

        /// <summary>
        /// 播放普通音频
        /// </summary>
        /// <param name="_ab">ab包</param>
        /// <param name="_audioName">音乐名称（Assets下完整路径， 带文件格式后缀）</param>
        /// <param name="action">音效结束事件</param>
        /// <param name="isAB"></param>
        /// <param name="_volum"></param>
        public void PlayNormalAudio(string _ab, string _audioName, Action action = null, bool isAB = true, float _volum = 1)
        {
           StartCoroutine(PlayAudio(_ab, _audioName, false, action, isAB, _volum));
        }

        private IEnumerator PlayAudio(string _ab, string _audioName, bool isLoop, Action action = null, bool isAB = true, float _volum = 1)
        {
            while(audioItem == null)
            {
                yield return null;
            }
            LoadAudio(_ab, _audioName, (aud) =>
              {
                  if (aud != null)
                  {
                      //AudioItem item = Instantiate(audioItem);
                      AudioItem item = GameObjectPool.Instance.CreateObject("AudioItem", audioItem).GetComponent<AudioItem>();
                      item.Play(aud, isLoop, _volum * AudioManager.audioVolum, action);
                      if (isLoop)
                      {
                          CurrentBGM.Add(aud.name, item);
                      }
                      else
                      {
                      }
                      AllAudioItem.Add(item);
                  }
              }, isAB);
        }

        /// <summary>
        /// 停止播放（背景音乐）
        /// </summary>
        /// <param name="_audioName">背景音乐名称（非全路径）</param>
        public void StopAudio(string _audioName)
        {
            if (CurrentBGM.ContainsKey(_audioName))
            {
                AudioItem item = CurrentBGM[_audioName];
                item.Stop();
                CurrentBGM.Remove(_audioName);
                if(AllAudioItem.Contains(item))
                {
                    AllAudioItem.Remove(item);
                }
            }
        }

        private void LoadAudio(string _ab, string _path, Action<AudioClip> _action, bool _isAB)
        {
            AssetBundlesManager.Instance.LoadAudioClip(_ab, _path, (str, aud) =>
              {
                  if (aud != null)
                  {
                      _action?.Invoke(aud);
                  }
              }, _isAB);
        }

        private void LoadAudioItem()
        {
            AssetBundlesManager.Instance.LoadAsset("", "Assets/Resources/AudioItem.prefab", (item) =>
              {
                  if (item != null)
                  {
                      audioItem = item as GameObject;
                  }
              }, false);
        }
    }
}